package org.xmonkey.notifier.model;

import java.util.HashMap;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.dom.ASTNode;
import org.xmonkey.Messages;
import org.xmonkey.util.Log;

/**
 * This class represents all the subscriptions to a specific IProject.
 * For each type of node that it is possible to find visiting that project, there
 * is an ordered list of clients that must be notified. 
 * @author jacopom
 *
 */
public class ProjectNodeSubscriptions extends HashMap<Integer, OrderedSubscribersList>{

	private static final long serialVersionUID = -1028353058888192158L;
	private final IProject project;
	
	public ProjectNodeSubscriptions(IProject project){
		this.project = project;
	}
	
	public String toString(){
		StringBuilder stringBuilder = new StringBuilder();
		
		for(Integer i : this.keySet()){
			stringBuilder.append(Messages.ProjectSubscriptions_0);
			stringBuilder.append(ASTNode.nodeClassForType(i));
			stringBuilder.append(Messages.ProjectSubscriptions_1);
			stringBuilder.append(this.get(i).toString());
			stringBuilder.append(Messages.ProjectSubscriptions_2);
		}
	
		return stringBuilder.toString();
	}

	/**
	 * Removes all the subscriptions for a given subscriber
	 * @param subscriber
	 */
	public void removeSubscriptionsFor(ISubscriber subscriber) {
		
		// for all the node types
		for(Integer ASTKey : this.keySet()){
			// get the list of subscribers
			OrderedSubscribersList orderedList = this.get(ASTKey);
			// and remove the specific subscriber, if there
			boolean deletion = orderedList.removeSubscriptionsFor(subscriber);
			
			if (deletion){
				StringBuilder infoMessage = new StringBuilder();
				infoMessage.append(Messages.ProjectSubscriptions_3);
				infoMessage.append(project.getName());
				infoMessage.append(Messages.ProjectSubscriptions_4);
				infoMessage.append(ASTNode.nodeClassForType(ASTKey).getName());
				infoMessage.append(Messages.ProjectSubscriptions_5);
				infoMessage.append(subscriber.getSubscriberName());
				
				Log.printInfo(infoMessage.toString(), null);
			}
		}
		
	}

	/**
	 * Notify all the subscribers that subscribed to a specific node
	 * @param node
	 */
	public void notifyVisit(ASTNode node) {
		if (this.containsKey(node.getNodeType())){
			// let us shallow copy the list, so that clients can potentially change the original one
			OrderedSubscribersList subscribers = new OrderedSubscribersList(this.get(node.getNodeType()));
			subscribers.notifyVisit(project, node);
		}
	}

}
